/*
 * Copyright 2010    Sylvere RICHARD
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.infotrafficlux.server.service;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.appengine.api.datastore.GeoPt;
import com.google.infotrafficlux.server.bean.Parking;
import com.google.infotrafficlux.server.dao.ParkingDao;

/**
 * @author sly
 * 
 */
@Service
public class ParkingUpdaterImpl {

	/**
	 * 
	 */
	public static final String PARK_AND_RIDE = "parkAndRide";

	public static final String GARE = "Gare";

	public static final String CENTRE = "Centre";
	
	public static final String KIRCHBERG = "Kirchberg";


	private final String url = "http://service.vdl.lu/export/circulation_guidageparking.php?vdl_f=detail&vdl_id=";

	public final int maxPkg = 30;

	private ParkingDao parkingDao;

	/**
	 * @return the parkingDao
	 */
	public ParkingDao getParkingDao() {
		return parkingDao;
	}

	/**
	 * @param parkingDao
	 *            the parkingDao to set
	 */
	@Autowired
	public void setParkingDao(ParkingDao parkingDao) {
		this.parkingDao = parkingDao;
	}

	public ParkingUpdaterImpl() {
	}

	public void updPkg(int which) {
		try {

			final String result = UrlFetcherHelper.fetchUrl(url + which);

			Parking pkg = parseAsPakingUpdater(result);

			getParkingDao().insertOrUpdate(pkg);

		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * @param result
	 * @return
	 */
	private Parking parseAsPakingUpdater(String result) {
		int actu = result.indexOf("<p>Actualis");
		if (actu == -1) {
			return null;
		}
		result = result.substring(actu);

		int script = result.indexOf("<script");
		if (script == -1) {
			return null;
		}
		final String firstPart = result.substring(0, script);

		final String regexp = "Actualis.+?\\: (.+?)<.+?Valeurs actuelles.+?td colspan='5' style='font-weight.+?\\>(.+?)\\<\\/td\\>.+?td class='bc'\\>(\\d+)\\<\\/td\\>.+?\\<td class='bc'\\>(\\d+)\\<\\/td\\>.+";

		Pattern p = Pattern.compile(regexp);
		Matcher m = p.matcher(firstPart);
		if (m.find() == false) {
			return null;
		}

		final Parking park = new Parking();
		park.setTimestamp(m.group(1));
		park.setDesc(m.group(2));
		park.setCapacity(Integer.valueOf(m.group(3)).intValue());
		park.setAvailable(Integer.valueOf(m.group(4)).intValue());
		park.setLocation(getLocation(result));
		park.setQuarter(getQuarter(result));

		return park;
	}

	/**
	 * @param result
	 * @return
	 */
	private String getQuarter(String result) {
		int deb = result.indexOf("Quartier&nbsp;:");
		if (deb == -1) {
			return PARK_AND_RIDE;
		}
		
		String regexp = "Quartier&nbsp;\\:\\<\\/td\\>\\<td class='bl' valign='top'\\>(.+?)\\<\\/td\\>";
		result = result.substring(deb);

		Pattern p = Pattern.compile(regexp);
		Matcher m = p.matcher(result);
		if (m.find() == false) {
			return "unknown";
		}
		return m.group(1);
	}

	/**
	 * @param result
	 * @return
	 */
	private GeoPt getLocation(String result) {
		int deb = result.indexOf("td class='r' valign='top'>Coordonn");
		if (deb == -1) {
			return new GeoPt(0F, 0F);
		}
		String regexp = "td class='r' valign='top'\\>Coordonn.+?\\<\\/td\\>\\<td class='bl' valign='top'\\>([0-9.]+), ([0-9.]+)\\<\\/td\\>";
		result = result.substring(deb);

		Pattern p = Pattern.compile(regexp);
		Matcher m = p.matcher(result);
		if (m.find() == false) {
			return new GeoPt(0F, 0F);
		}
		return new GeoPt(Float.valueOf(m.group(1)).floatValue(), Float.valueOf(
				m.group(2)).floatValue());
	}

}
